在Day 20的時候我們有提到利用cmakelist產生Makefile,並且透過產生的Makefile編譯出執行檔執行程式,今天我們要來一步一步解析昨天提到的CMakelist.txt以及下的指令一系列的對應關係...
由前面的文章我們可以知道Cmake是輔助生成Makefile的工具,在Day19的時候我們有提到Cmake的幾個常見的指令跟用途,今天我們就要結合前面幾篇的文章,綜合解讀一下Cmake的標準寫法。
首先~我們回到Day 20的這個CMakeLists.txt例子:
這個 CMakeLists.txt 主要是 描述 下面的資訊
但你可能會問:
不對呀?
cmake應該是用來產生makefile的工具,那Cmakelist.txt裡面為什麼沒有關於要用到 Makefile的建置資訊?.........
有Cmakelist.txt就可以建置了,
為什麼前面有提到 cmakelist.txt 跟 makefile是不同層級的工具?
那我們這樣解釋好了... cmake, makefile, make 的層級關係其實是這樣的
最高層:CMake (meta-build system / generator)
↳ 負責跨平台抽象,把 target 屬性轉換成對應 backend 語法
中層: 生成的檔案 (Makefile, build.ninja, .sln, .xcodeproj)
↳ 這些是 build description,描述怎麼建置
底層: Build tools (GNU Make, Ninja, MSBuild, Xcodebuild)
↳ 真正呼叫 gcc/clang/msvc 去編譯/連結
gnu make 的官網把make這樣定義
GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files.
Make 本身跟 Ninja 一樣是屬於 build system 專門來控制編譯的編譯過程
而CMake 算是 build system generator ,他不是直接控制編譯器編譯source code,而是編出build executor去控制編譯器執行編譯,主要可以理解成下面的幾個重點
Cmakelist.txt裡描述要編什麼、怎麼編
Cmake會根據"下指令 -G" 的資訊產生相對應的makefile 或是 Ninja,就是Day20的最後那行產生makefile的指令
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug # 產生Makefilie
而其實上面的指令可以有一系列的變化.... (也太多...)
不同指令可以產生不同的 build system的工具,例如 makefile,Ninja...
下面整理了常見的用法範例
指令 | 說明 |
---|---|
cmake -S . -B build |
最基本用法。 -S . 表示來源(source)目錄是當前目錄(CMakeLists.txt 在這裡)。 -B build 表示輸出的「建置目錄」是 build/ 。 預設會用系統的 default generator(通常是 Unix Makefiles 或 Ninja,依環境而定)。 |
cmake -S . -B build -G "Unix Makefiles" ![]() |
指定 generator 為「Unix Makefiles」。 → 會在 build/ 裡產生 Makefile ,之後用 make 來編譯。 |
cmake -S . -B build -G "Ninja" |
指定 generator 為 Ninja。 → 會在 build/ 裡產生 build.ninja ,之後用 ninja 來編譯。 (Ninja 比 Make 快很多,常見於大型專案或 CI/CD pipeline) |
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug Day20中有提到的 |
指定 建置型態 為 Debug。 → 編譯時會加上 -g (debug symbols)、停用最佳化,方便除錯。 預設型態通常是空的(或 Release,依系統設定)。 |
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release |
指定為 Release。 → 編譯時會加上 -O3 (最佳化),不包含 debug symbols。 適合發佈執行檔。 |
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo |
介於 Release 和 Debug 之間。 → 加上最佳化 -O2 ,但仍保留 debug symbols。 適合邊測試效能邊除錯。 |
cmake -S . -B build -DCMAKE_BUILD_TYPE=MinSizeRel |
最小體積模式。 → 加上 -Os ,盡量壓縮程式大小。 常用於嵌入式或發佈極小安裝包。 |
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=arm-gcc-toolchain.cmake |
指定 交叉編譯的工具鏈檔。 → 例如在 x86 機器上編 ARM 程式。 arm-gcc-toolchain.cmake 裡會寫明編譯器前綴、sysroot 等設定。 |
cmake --build build |
執行建置。 CMake 會自動呼叫對應的工具: - 如果 generator 是 Makefile → 呼叫 make - 如果 generator 是 Ninja → 呼叫 ninja |
cmake --install build --prefix ./dist |
把建置結果安裝到指定路徑 ./dist 。 (安裝規則在 CMakeLists.txt 裡用 install() 定義)。 |